﻿package com.mui.core
{
    import __AS3__.vec.*;
    import com.gengine.debug.*;
    import com.gengine.global.*;
    import com.mui.events.*;
    import flash.display.*;
    import flash.events.*;
    import flash.net.*;
    import flash.system.*;
    import flash.utils.*;

    public class Library extends EventDispatcher
    {
        private var _loaderContext:LoaderContext;
        private var _enterFrameDispatcher:Sprite;
        private var _embeddedLoaders:Array;
        private var _runtimeLoaders:Array;
        private var _embeddedComplete:Boolean;
        private var _runtimeCompletes:Array;
        private var _runtimeComplete:Boolean;
        private var _name:String;
        private var _bytesLoaded:Number = 0;
        private var _bytesTotal:Number = 0;
        private var _LoaderContext:LoaderContext;
        private var _dicUrlName:Dictionary;
        private var _this:Library;
        private var _loadUrl:Vector.<String>;
        private var _loadResName:Vector.<String>;
        private var _isLoading:Boolean = false;

        public function Library(param1:String)
        {
            this._LoaderContext = new LoaderContext();
            this._dicUrlName = new Dictionary();
            this._loadUrl = new Vector.<String>;
            this._loadResName = new Vector.<String>;
            this._this = this;
            this._name = param1;
            this.initialize();
            this._loaderContext = new LoaderContext(false, new ApplicationDomain(null));
            return;
        }// end function

        public function get name() : String
        {
            return this._name;
        }// end function

        public function get bytesLoaded() : Number
        {
            return this._bytesLoaded;
        }// end function

        public function get bytesTotal() : Number
        {
            return this._bytesTotal;
        }// end function

        public function get complete() : Boolean
        {
            return this._embeddedComplete && this._runtimeComplete;
        }// end function

        public function get embeddedComplete() : Boolean
        {
            return this._embeddedComplete;
        }// end function

        public function get runtimeComplete() : Boolean
        {
            return this._runtimeComplete;
        }// end function

        public function loadSWF(param1:String, param2:String = "", param3:Boolean = false) : void
        {
            var _loc_4:* = new LibraryLoader(param3);
            this._dicUrlName[this.getNoVersionUrl(param1)] = param2;
            _loc_4.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, this.onLoaderProgress, false, 0, true);
            _loc_4.contentLoaderInfo.addEventListener(Event.COMPLETE, this.onLoaderComplete, false, 0, true);
            _loc_4.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, this.onIOErrorHandler, false, 0, true);
            _loc_4.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onIOErrorHandler, false, 0, true);
            _loc_4.load(new URLRequest(param1), this._loaderContext);
            this._runtimeLoaders.push(_loc_4);
            this._runtimeCompletes.push(false);
            return;
        }// end function

        private function getNoVersionUrl(param1:String) : String
        {
            var _loc_2:* = param1.indexOf("?");
            if (_loc_2 >= 0)
            {
                return param1.slice(0, _loc_2);
            }
            return param1;
        }// end function

        public function embedSWF(param1:Class) : void
        {
            var _loc_2:* = new LibraryLoader();
            _loc_2.loadBytes(new param1 as ByteArray, this._loaderContext);
            this._embeddedLoaders.push(_loc_2);
            return;
        }// end function

        public function loadSWFS(param1:Array) : void
        {
            this._runtimeComplete = false;
            var _loc_2:* = param1.length;
            var _loc_3:int = 0;
            while (_loc_3 < _loc_2)
            {
                
                this.loadSWF(param1[_loc_3] as String);
                _loc_3++;
            }
            return;
        }// end function

        public function embedSWFS(param1:Array) : void
        {
            var _loc_2:LibraryLoader = null;
            var _loc_3:Class = null;
            if (this._enterFrameDispatcher.hasEventListener(Event.ENTER_FRAME))
            {
                this._enterFrameDispatcher.removeEventListener(Event.ENTER_FRAME, this.onEnterFrame);
            }
            this._embeddedComplete = false;
            var _loc_4:* = param1.length;
            var _loc_5:int = 0;
            while (_loc_5 < _loc_4)
            {
                
                _loc_3 = Class(param1[_loc_5]);
                _loc_2 = new LibraryLoader();
                _loc_2.loadBytes(new _loc_3 as ByteArray, this._loaderContext);
                this._embeddedLoaders.push(_loc_2);
                _loc_5++;
            }
            this._enterFrameDispatcher.addEventListener(Event.ENTER_FRAME, this.onEnterFrame, false, 0, true);
            return;
        }// end function

        public function hasDefinition(param1:String) : Boolean
        {
            return this._loaderContext.applicationDomain.hasDefinition(param1);
        }// end function

        public function getDefinition(param1:String) : Class
        {
            var _loc_2:* = this._loaderContext.applicationDomain.getDefinition(param1) as Class;
            if (_loc_2)
            {
                return _loc_2;
            }
            ThrowError.show("ReferenceError: Error #1065: Variable " + param1 + " is not defined.");
            return null;
        }// end function

        public function contains(param1:String) : Boolean
        {
            var _loc_2:LibraryLoader = null;
            var _loc_3:* = this._embeddedLoaders.length;
            var _loc_4:int = 0;
            while (_loc_4 < _loc_3)
            {
                
                _loc_2 = LibraryLoader(this._embeddedLoaders[_loc_4]);
                if (_loc_2.contentLoaderInfo.applicationDomain.hasDefinition(param1))
                {
                    return true;
                }
                _loc_4++;
            }
            return false;
        }// end function

        public function reset() : void
        {
            this.destroy();
            this.initialize();
            return;
        }// end function

        public function destroy() : void
        {
            var _loc_1:LibraryLoader = null;
            var _loc_2:int = 0;
            var _loc_3:int = 0;
            if (this._enterFrameDispatcher.hasEventListener(Event.ENTER_FRAME))
            {
                this._enterFrameDispatcher.removeEventListener(Event.ENTER_FRAME, this.onEnterFrame);
            }
            _loc_2 = this._runtimeLoaders.length;
            _loc_3 = 0;
            while (_loc_3 < _loc_2)
            {
                
                _loc_1 = LibraryLoader(this._runtimeLoaders[_loc_3]);
                if (!this._runtimeCompletes[_loc_3])
                {
                    _loc_1.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, this.onLoaderProgress);
                    _loc_1.close();
                }
                else
                {
                    _loc_1.unload();
                }
                _loc_3++;
            }
            _loc_2 = this._embeddedLoaders.length;
            _loc_3 = 0;
            while (_loc_3 < _loc_2)
            {
                
                _loc_1 = LibraryLoader(this._embeddedLoaders[_loc_3]);
                _loc_1.unload();
                _loc_3++;
            }
            this._embeddedLoaders = null;
            this._runtimeLoaders = null;
            this._runtimeCompletes = null;
            this._enterFrameDispatcher = null;
            this._name = null;
            this._bytesLoaded = undefined;
            this._bytesTotal = undefined;
            return;
        }// end function

        private function initialize() : void
        {
            this._embeddedLoaders = new Array();
            this._runtimeLoaders = new Array();
            this._runtimeCompletes = new Array();
            this._enterFrameDispatcher = new Sprite();
            this._bytesLoaded = 0;
            this._bytesTotal = 0;
            return;
        }// end function

        private function onEnterFrame(event:Event) : void
        {
            this._enterFrameDispatcher.removeEventListener(Event.ENTER_FRAME, this.onEnterFrame);
            this._embeddedComplete = true;
            dispatchEvent(new LibraryEvent(LibraryEvent.EMBED_COMPLETE, null, false, false));
            return;
        }// end function

        private function onLoaderProgress(event:ProgressEvent) : void
        {
            this.checkLoadersProgress();
            return;
        }// end function

        private function onLoaderComplete(event:Event) : void
        {
            var _loc_3:String = null;
            var _loc_4:int = 0;
            var _loc_5:int = 0;
            var _loc_2:* = LibraryLoader((event.currentTarget as LoaderInfo).loader);
            if (_loc_2)
            {
                this.removeLoaderEvent(_loc_2);
                _loc_3 = this._dicUrlName[this.getNoVersionUrl(_loc_2.getUrl())];
                dispatchEvent(new LibraryEvent(LibraryEvent.SINGLELOAD_COMPLETE, _loc_3, false, false));
            }
            if (this._runtimeLoaders)
            {
                _loc_4 = this._runtimeLoaders.length;
                _loc_5 = 0;
                while (_loc_5 < _loc_4)
                {
                    
                    if (_loc_2 == LibraryLoader(this._runtimeLoaders[_loc_5]))
                    {
                        this._runtimeCompletes[_loc_5] = true;
                        break;
                    }
                    _loc_5++;
                }
            }
            this.checkLoadersProgress(true);
            return;
        }// end function

        private function onIOErrorHandler(event:ErrorEvent) : void
        {
            if (Global.isDebugModle)
            {
                dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, event.text));
            }
            if (event.target.loader is LibraryLoader)
            {
                this.removeLoaderEvent(event.target.loader as LibraryLoader);
            }
            return;
        }// end function

        private function removeLoaderEvent(param1:LibraryLoader) : void
        {
            if (param1)
            {
                param1.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, this.onLoaderProgress, false);
                param1.contentLoaderInfo.removeEventListener(Event.COMPLETE, this.onLoaderComplete, false);
                param1.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, this.onIOErrorHandler, false);
                param1.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onIOErrorHandler, false);
            }
            return;
        }// end function

        private function checkLoadersProgress(param1:Boolean = false) : void
        {
            var _loc_4:LibraryLoader = null;
            var _loc_2:Number = 0;
            var _loc_3:Number = 0;
            param1 = true;
            var _loc_5:* = this._runtimeLoaders.length;
            var _loc_6:int = 0;
            while (_loc_6 < _loc_5)
            {
                
                _loc_4 = LibraryLoader(this._runtimeLoaders[_loc_6]);
                _loc_2 = _loc_2 + _loc_4.contentLoaderInfo.bytesTotal;
                _loc_3 = _loc_3 + _loc_4.contentLoaderInfo.bytesLoaded;
                if (!this._runtimeCompletes[_loc_6])
                {
                    param1 = false;
                }
                _loc_6++;
            }
            this._bytesLoaded = _loc_3;
            this._bytesTotal = _loc_2;
            if (param1)
            {
                this._runtimeComplete = true;
                dispatchEvent(new LibraryEvent(LibraryEvent.LOAD_COMPLETE, null, false, false));
            }
            else
            {
                dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, false, false, _loc_3, _loc_2));
            }
            return;
        }// end function

    }
}
